/*
 * Copyright 2007 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.neusoft.wenjoy.bootstrap;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.LinkedList;

/**
 *
 * @author vvenLi@gmail.com
 */
public class BootstrapBeanFactory implements BeanFactory {
	private BeanFactory beanFactory = null;

	public BootstrapBeanFactory(String homedir) throws IOException, ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException,	InvocationTargetException {
		URL[] urls = (new PluginClassPath()).getURLs(homedir);
		ClassLoader loader = new URLClassLoader(urls, Thread.currentThread().getContextClassLoader());

		beanFactory = createBeanFactory(loader, homedir);
	}

	private BeanFactory createBeanFactory(ClassLoader loader, String homedir)
			throws ClassNotFoundException, NoSuchMethodException,
			InstantiationException, IllegalAccessException,
			InvocationTargetException {

		Class clazz = loader
				.loadClass("com.neusoft.wenjoy.core.PluginBeanFactory");
		Class[] argsClass = new Class[] { String.class };
		Constructor constructor = clazz.getConstructor(argsClass);

		BeanFactory factory = (BeanFactory) constructor
				.newInstance(new String[] { homedir });

		return factory;
	}

	public Object getBean(String name) {
		return beanFactory.getBean(name);
	}

	private class PluginClassPath {

		private String FILE_SCHEMA = "file:";

		public URL[] getURLs(String homedir) throws IOException {

			LinkedList list = new LinkedList();

			File home = new File(homedir);
			if (!home.exists()) {
				throw new java.io.FileNotFoundException(homedir
						+ " directory does not exist.");
			}
			list.add(new URL(FILE_SCHEMA + home.getCanonicalPath() + "/" ));

			File[] libJars = getJars(new File(home, "lib"));
			for (int i = 0; i < libJars.length; i++) {
				list.add(new URL(FILE_SCHEMA + libJars[i].getCanonicalPath()));
			}

			File pluginsPath = new File(home, "plugins");
			if (!pluginsPath.exists()) {
				throw new java.io.FileNotFoundException(
						"plugins directory does not exist.");
			}

			File[] plugins = pluginsPath.listFiles();
			for (int i = 0; i < plugins.length; i++) {
				list.add(new URL(FILE_SCHEMA + plugins[i].getCanonicalPath() + "/" ));

				File[] jars = getJars(plugins[i]);
				for (int j = 0; j < jars.length; j++) {
					list.add(new URL(FILE_SCHEMA + jars[j].getCanonicalPath()));
				}
			}
			System.out.println(list);
			return (URL[]) list.toArray(new URL[list.toArray().length]);
		}

		private File[] getJars(File file) {
			return file.listFiles(new FilenameFilter() {
				public boolean accept(File dir, String name) {
					if (name.endsWith(".jar") || name.endsWith(".zip")
							|| name.endsWith(".JAR") || name.endsWith(".ZIP")
							|| name.endsWith(".Jar") || name.endsWith(".Zip")) {
						return true;
					}
					return false;
				}
			});
		}
	}

}
